#include <iostream>

#include <functional>

#include <nemesis.h>

using namespace std;

class Object {
public:
   Object ();

   const std::string& getName () const throw () { return a_name; }

private:
   std::string a_name;
};

struct SortByName {
   static const std::string& value (const Object* oo) throw () { return oo->getName (); }
};

string generate ()
{
   string result;
   char aux [34];

   int len = 1 + rand () % 32;

   int ii;
   for (ii = 0; ii < len; ii ++)
      aux [ii] = char (rand () % 28 + 'A');
   aux [ii] = 0;

   return result = aux;
}

Object::Object ()
{
   a_name = generate ();
}

void run () 
   throw (RuntimeException)
{
   typedef SortedVector <Object, SortByName, std::string> container;
   typedef container::iterator iterator;
   container sorted;

   static const int MaxIndex = 64;

   Object** object;

   object = new Object* [MaxIndex];

   for (int ii = 0; ii < MaxIndex; ii ++) {
      object [ii] = new Object;
      sorted.add (object [ii]);
   }

   for (iterator ii = sorted.begin (), maxii = sorted.end (); ii != maxii; ii ++) 
       cout << container::data (ii)->getName () << endl;
   cout << endl << endl;

   string value;
   int counter;
   int found;

   counter = found = 0;

   for (int loop = 0; loop < 1000; loop ++) {
      for (int ii = 0; ii < MaxIndex; ii ++, counter ++) {
        value = ((rand () % 100) > 50) ? object [ii]->getName (): generate ();
        if (sorted.find (value) != NULL)
           found ++;
      }
   }

   cout << "Counter: " << counter << " | Found: " << found << endl << endl;
}

int main (int argc, const char** argv)
{
   try {
      Logger::setLevel (Logger::Debug); 
      Logger::initialize ("testfunctions", new TraceWriter ("file.trace", 2048000));
  
      run ();
   }
   catch (Exception& ex) {
      cout << ex.asString () << endl;
   }
   
   return 0;
}

